<template>
  <div>
    <!-- 顶部统计区 -->
    <div class="container mt20 w1200">
      <div class="stat-grid">
        <div class="stat-item">
          <span class="stat-num">{{ headerData.totalMembers }}</span>
          <p class="left">学员总数</p>
        </div>
        <div class="stat-item">
          <span class="stat-num">{{ headerData.activeMembers }}</span>
          <p class="left">活跃学员</p>
        </div>
        <div class="stat-item">
          <span class="stat-num">{{ headerData.totalReservations }}</span>
          <p class="left">预约总数</p>
        </div>
        <div class="stat-item">
          <el-button type="success" @click="refreshData">刷新数据</el-button>
        </div>
      </div>
    </div>

    <!-- 图表区域 -->
    <div class="container mt20 w1200 chart-container">
      <div ref="chartDom1" class="chart-box"></div>
      <div ref="chartDom3" class="chart-box"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue'
import * as echarts from 'echarts'
import axios from 'axios'

const headerData = ref({
  totalMembers: 0,
  activeMembers: 0,
  totalReservations: 0
})

const chartDom1 = ref(null)
const chartDom3 = ref(null)
let myChartLine = null
let myChartPie = null

const option1 = reactive({
  legend: { data: ['流失', '新增'], left: '10%' },
  tooltip: { trigger: 'axis' },
  xAxis: {
    type: 'category',
    data: Array.from({ length: 12 }, (_, i) => (i + 1) + '月'),
    name: '月份',
    axisLine: { onZero: true },
    splitLine: { show: false }
  },
  yAxis: { name: '人数', type: 'value' },
  grid: { bottom: 100 },
  series: [
    { name: '流失', color: 'DarkGray', type: 'bar', stack: 'one', data: [] },
    { name: '新增', color: 'PaleGreen', type: 'bar', stack: 'one', data: [] }
  ]
})

const option3 = reactive({
  title: {
    text: '课时卡统计',
    subtext: '绑定课时卡数量',
    left: '37%',
    top: 0,
    textStyle: {
      fontSize: 18,
      fontWeight: 'bold'
    }
  },
  tooltip: {
    trigger: 'item',
    formatter: '{b}: {c} ({d}%)'
  },
  legend: {
    orient: 'vertical',
    type: 'scroll',
    right: 10,
    top: 'middle',
    textStyle: {
      fontSize: 14,
      overflow: 'break' // 避免文字省略
    }
  },
  series: [
    {
      name: '卡片类型',
      type: 'pie',
      radius: [50, 140],
      center: ['45%', '55%'], 
      roseType: 'area',
      itemStyle: {
        borderRadius: 10
      },
      emphasis: {
        label: {
          show: true,
          fontSize: 20,
          fontWeight: 'bold'
        }
      },
      label: {
        show: true,
        formatter: '{b}', // 显示全部名称
        fontSize: 14,
        color: '#333'
      },
      labelLine: {
        show: true,
        length: 20,
        length2: 10,
        smooth: true
      },
      data: []
    }
  ]
})


function getCardLevel(cardName) {
  if (!cardName) return ''
  if (cardName.includes('初级')) return '初级卡'
  if (cardName.includes('中级')) return '中级卡'
  if (cardName.includes('高级')) return '高级卡'
  if (cardName.includes('进阶')) return '进阶卡'
  if (cardName.includes('体验')) return '体验卡'
  if (cardName.includes('特惠')) return '特惠卡'
  if (cardName.includes('基础')) return '基础卡'
  return '普通卡'
}

async function drawChart1() {
  if (myChartLine) {
    myChartLine.dispose()
    myChartLine = null
  }
  myChartLine = echarts.init(chartDom1.value)

  try {
    const [studentRes, statsRes] = await Promise.all([
      axios.get('http://localhost:8080/api/students'),
      axios.get('http://localhost:8080/api/statistics')
    ])

    const students = Array.isArray(studentRes.data) ? studentRes.data : studentRes.data.data
    const stats = Array.isArray(statsRes.data) ? statsRes.data : statsRes.data.data

    const newMap = Array(12).fill(0)
    students.forEach(s => {
      if (s.enrollmentDate) {
        const month = new Date(s.enrollmentDate).getMonth()
        newMap[month]++
      }
    })

    const lostMap = Array(12).fill(0)
    stats.forEach(stat => {
      if (stat.expireDate && stat.status !== 'active') {
        const month = new Date(stat.expireDate).getMonth()
        lostMap[month]++
      }
    })

    option1.series[0].data = lostMap
    option1.series[1].data = newMap

    myChartLine.setOption(option1)
  } catch (e) {
    console.error('drawChart1 error:', e)
  }
}

async function drawChart3() {
  if (myChartPie) {
    myChartPie.dispose()
    myChartPie = null
  }
  myChartPie = echarts.init(chartDom3.value)

  try {
    const res = await axios.get('http://localhost:8080/api/class-cards')
    const cards = Array.isArray(res.data) ? res.data : res.data.data

    const typeMap = {}
    cards.forEach(card => {
      const type = getCardLevel(card.cardName)
      typeMap[type] = (typeMap[type] || 0) + 1
    })

    option3.series[0].data = Object.entries(typeMap).map(([name, value]) => ({ name, value }))
    myChartPie.setOption(option3)
  } catch (e) {
    console.error('drawChart3 error:', e)
  }
}

async function fetchHeaderData() {
  try {
    const studentRes = await axios.get('http://localhost:8080/api/students')
    const students = Array.isArray(studentRes.data) ? studentRes.data : studentRes.data.data
    headerData.value.totalMembers = students.length

    const statsRes = await axios.get('http://localhost:8080/api/statistics')
    const stats = Array.isArray(statsRes.data) ? statsRes.data : statsRes.data.data

    const activeStudentsSet = new Set()
    stats.forEach(stat => {
      if (stat.status === 'active' && stat.studentId) {
        activeStudentsSet.add(stat.studentId)
      }
    })
    headerData.value.activeMembers = activeStudentsSet.size

    const reservationRes = await axios.get('http://localhost:8080/api/reservation-settings')
    const reservations = Array.isArray(reservationRes.data) ? reservationRes.data : reservationRes.data.data
    headerData.value.totalReservations = reservations.reduce((sum, r) => sum + (r.maxReservations || 0), 0)

  } catch (e) {
    console.error('fetchHeaderData error:', e)
  }
}

async function refreshData() {
  await nextTick()
  await Promise.all([
    fetchHeaderData(),
    drawChart1(),
    drawChart3()
  ])
}

onMounted(() => {
  refreshData()
})
</script>

<style scoped lang="less">
.mt20 {
  margin-top: 20px;
}
.w1200 {
  max-width: 1200px;
  margin: 0 auto;
}

.stat-grid {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
}
.stat-item {
  flex: 1 1 23%;
  min-width: 200px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
}
.stat-num {
  font-size: 25px;
  font-weight: bold;
}
.left {
  text-align: left;
}

.chart-container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 30px;
}
.chart-box {
  flex: 1 1 48%;
  height: 400px;
  min-width: 300px;
}

@media (max-width: 768px) {
  .chart-box {
    flex: 1 1 100%;
  }
}
</style>
